/**
 * @module vim-loader
 */

import { assign } from 'radash'
import { Transparency } from './geometry'
import { Matrix4, Vector3, Quaternion, Euler } from 'three'

/**
 * Represents settings for configuring the behavior and rendering of a vim object.
 */
export type VimSettings = {

  /**
   * The positional offset for the vim object.
   */
  position: Vector3

  /**
   * The XYZ rotation applied to the vim object.
   */
  rotation: Vector3

  /**
   * The scaling factor applied to the vim object.
   */
  scale: number

  /**
   * The matrix representation of the vim object's position, rotation, and scale.
   * Setting this will override individual position, rotation, and scale properties.
   */
  matrix: Matrix4

  /**
   * Determines whether objects are drawn based on their transparency.
   */
  transparency: Transparency.Mode

  /** 
   * Set to true to enable verbose HTTP logging.
   */
  verboseHttp: boolean


  /** 
   * Set to true to stream geometry to the scene. Only supported with vimx files.
   */
  progressive: boolean

  /**
   * The time in milliseconds between each scene refresh during progressive loading.
   */
  progressiveInterval: number



  /** 
   * The instance indices of objects to load. All objects are loaded if no value is provided in the legacy pipeline.
   */
  legacyInstances: number[]

  /** 
   * Set to true to prevent downloading strings in the legacy pipeline.
   */
  legacyNoStrings: boolean

  /** 
   * Set to true to prevent downloading the element/geometry map in the legacy pipeline.
   */
  legacyNoMap: boolean

  /** 
   * Set to true to prevent downloading the header in the legacy pipeline.
   */
  legacyNoHeader: boolean

  /** 
   * Set to true to load and display rooms in the legacy pipeline.
   */
  legacyLoadRooms: boolean
}

/**
 * Default configuration settings for a vim object.
 */
export const defaultConfig: VimSettings = {
  position: new Vector3(),
  rotation: new Vector3(),
  scale: 1,
  matrix: undefined,
  transparency: 'all',
  verboseHttp: false,

  // progressive
  progressive: false,
  progressiveInterval: 1000,

  //legacy

  legacyInstances: undefined,
  legacyNoStrings: false,
  legacyNoMap: false,
  legacyNoHeader: false,
  legacyLoadRooms: false,

}

/**
 * Represents a partial configuration of settings for a vim object.
 */
export type VimPartialSettings = Partial<VimSettings>

/**
 * Wraps Vim options, converting values to related THREE.js types and providing default values.
 * @param {VimPartialSettings} [options] - Optional partial settings for the Vim object.
 * @returns {VimSettings} The complete settings for the Vim object, including defaults.
 */
export function getFullSettings(options?: Partial<VimSettings>) {
  const merged = options
    ? assign(defaultConfig, options) as VimSettings
    : defaultConfig

  merged.transparency = Transparency.isValid(merged.transparency!)
    ? merged.transparency
    : 'all'

  merged.matrix = merged.matrix ?? new Matrix4().compose(
    merged.position,
    new Quaternion().setFromEuler(
      new Euler(
        (merged.rotation.x * Math.PI) / 180,
        (merged.rotation.y * Math.PI) / 180,
        (merged.rotation.z * Math.PI) / 180
      )
    ),
    new Vector3(merged.scale, merged.scale, merged.scale)
  )

  return merged
}
